package remote

import (
	"apedge/pkg/configs"
	"apedge/pkg/protocol"
	"apedge/pkg/utils"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"time"

	"github.com/mitchellh/mapstructure"
)

func GetServiceResource(userInfo *protocol.UserInfoAAA) (float64, int32, int32, error) {
	var cpu float64
	var mem int32
	var npu int32
	var mixCpuPerNpu float64
	var mixMemPerNpu float64

	rsp, err := GetResourceFromAom(userInfo)
	if err != nil {
		return 0, 0, 0, err
	}
	for _, r := range rsp.Resources {
		cpuPerNpu := float64(r.CpuNum) * 0.8 / float64(r.NpuCount)
		memPerNpu := float64(r.Mem/1024/1024) * 0.8 / float64(r.NpuCount)
		if mixCpuPerNpu == 0 && mixMemPerNpu == 0 {
			mixCpuPerNpu = cpuPerNpu
			mixMemPerNpu = memPerNpu
		}
		if mixCpuPerNpu > cpuPerNpu {
			mixCpuPerNpu = cpuPerNpu
		}
		if mixMemPerNpu > memPerNpu {
			mixMemPerNpu = memPerNpu
		}
	}
	cpuStr := strconv.FormatFloat(mixCpuPerNpu, 'f', 2, 64)
	cpu, _ = strconv.ParseFloat(cpuStr, 64)
	mem = int32(mixMemPerNpu)
	npu = 1
	logger.Infof("cpu: %d \n mem: %d \n npu: %d \n", cpu, mem, npu)
	return cpu, mem, npu, nil
}

type GetResourceReq struct {
	Labels string `json:"labels"`
}

type GetResourceRsp struct {
	Resources []Resource `json:"resources"`
}

type Resource struct {
	SeriesType string `json:"seriesType"`
	CpuNum     int32  `json:"cpuNum"`
	Mem        int64  `json:"mem"`
	NpuCount   int32  `json:"npuCount"`
}

// 从运维中心获取 资源数据
func GetResourceFromAom(userInfo *protocol.UserInfoAAA) (GetResourceRsp, error) {
	var getResourceReq GetResourceReq
	var getResourceRsp GetResourceRsp
	var client = &http.Client{
		Timeout: time.Second * 10,
	}

	getResourceReq.Labels = configs.Config.Relevant.ResourceLabel
	data, err := json.Marshal(getResourceReq)
	if err != nil {
		return getResourceRsp, err
	}
	logger.Info("getResourceReq JSON: ", string(data))

	remoteUrl := utils.GetHttpUrl(configs.Config.Relevant.Service.AomSvc, AomGetResourceApi)
	remoteUrl = remoteUrl + "?labels=" + getResourceReq.Labels
	logger.Infoln("getResourceReq svc url: ", remoteUrl)

	req, err := http.NewRequest("GET", remoteUrl, nil)
	if err != nil {
		return getResourceRsp, err
	}
	req.Header.Set("Authorization", userInfo.Authorization)
	resp, err := client.Do(req)
	if err != nil {
		return getResourceRsp, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return getResourceRsp, fmt.Errorf("aom svc error %d %+v", resp.StatusCode, resp.Body)
	}

	var respBody protocol.APISuccessRsp
	err = json.NewDecoder(resp.Body).Decode(&respBody)
	if err != nil {
		return getResourceRsp, err
	}

	if respBody.Code != 0 {
		return getResourceRsp, fmt.Errorf("aom svc error %d %+v", respBody.Code, respBody.Msg)
	}
	logger.Infoln("-----------------------")
	ddd := respBody.Data
	asddad, _ := json.Marshal(&ddd)
	logger.Infoln(string(asddad))
	err = mapstructure.Decode(respBody.Data, &getResourceRsp)
	if err != nil {
		return getResourceRsp, err
	}

	logger.Infof("res: %+v", getResourceRsp)
	return getResourceRsp, nil
}

func GetResourceOfNpuNum(userInfo *protocol.UserInfoAAA) (int32, error) {
	var npuCount int32

	rsp, err := GetResourceFromAom(userInfo)
	if err != nil {
		return npuCount, err
	}
	for _, r := range rsp.Resources {
		npuCount += r.NpuCount
	}
	return npuCount, nil
}
